use axum::{
    http::StatusCode,
    response::{IntoResponse, Response},
    Json,
};
use serde_json::json;
use thiserror::Error;

#[derive(Error, Debug)]
pub enum AppError {
    #[error("Database error: {0}")]
    DatabaseError(#[from] sqlx::Error),
    
    #[error("Crypto error: {0}")]
    CryptoError(String),
    
    #[error("AI service error: {0}")]
    AIServiceError(String),
    
    #[error("WeChat error: {0}")]
    WeChatError(String),
    
    #[error("Validation error: {0}")]
    ValidationError(String),
    
    #[error("Not found: {0}")]
    NotFound(String),
    
    #[error("Internal server error: {0}")]
    InternalError(String),
    
    #[error("Parse error: {0}")]
    ParseError(String),
}

impl IntoResponse for AppError {
    fn into_response(self) -> Response {
        let (status, error_code, message) = match self {
            AppError::DatabaseError(err) => (
                StatusCode::INTERNAL_SERVER_ERROR,
                "DATABASE_ERROR",
                err.to_string(),
            ),
            AppError::CryptoError(msg) => (
                StatusCode::BAD_REQUEST,
                "CRYPTO_ERROR",
                msg,
            ),
            AppError::AIServiceError(msg) => (
                StatusCode::SERVICE_UNAVAILABLE,
                "AI_SERVICE_ERROR",
                msg,
            ),
            AppError::WeChatError(msg) => (
                StatusCode::BAD_REQUEST,
                "WECHAT_ERROR",
                msg,
            ),
            AppError::ValidationError(msg) => (
                StatusCode::BAD_REQUEST,
                "VALIDATION_ERROR",
                msg,
            ),
            AppError::NotFound(msg) => (
                StatusCode::NOT_FOUND,
                "NOT_FOUND",
                msg,
            ),
            AppError::InternalError(msg) => (
                StatusCode::INTERNAL_SERVER_ERROR,
                "INTERNAL_ERROR",
                msg,
            ),
            AppError::ParseError(msg) => (
                StatusCode::BAD_REQUEST,
                "PARSE_ERROR",
                msg,
            ),
        };

        let body = Json(json!({
            "error": {
                "code": error_code,
                "message": message,
                "details": {}
            }
        }));

        (status, body).into_response()
    }
}

pub type AppResult<T> = Result<T, AppError>;
